<Designer(GetType(WizardPageDesigner)), TypeConverter(GetType(WizardPageConverter)), ToolboxItem(False)> _
Public Class WizardPage
    Inherits System.Windows.Forms.ContainerControl

    Friend Wizard As Wizard

    'Wizard properties
    Private _strHeading As String = "Heading"
    Private _strDescription As String = "Sub Heading"

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call
        Initialize()
    End Sub

    'UserControl overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container()
    End Sub

#End Region

    <DefaultValue("Sub Heading"), Category("Wizard"), Description("The description displayed in the wizard when this page is displayed.")> _
    Public Property Description() As String
        Get
            Return _strDescription
        End Get
        Set(ByVal Value As String)
            _strDescription = Value
            If Not Wizard Is Nothing Then
                If Wizard.intSelectedPage = Wizard.Pages.IndexOf(Me) Then Wizard.Invalidate()
            End If
        End Set
    End Property

    <DefaultValue("Heading"), Category("Wizard"), Description("The main heading displayed in the wizard when this page is displayed.")> _
    Public Property Heading() As String
        Get
            Return _strHeading
        End Get
        Set(ByVal Value As String)
            _strHeading = Value
            If Not Wizard Is Nothing Then
                If Wizard.intSelectedPage = Wizard.Pages.IndexOf(Me) Then Wizard.Invalidate()
            End If
        End Set
    End Property

    Private Sub Initialize()
        'Set drawing styles
        SetStyle(ControlStyles.DoubleBuffer, True)
        SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Dim wrct As Rectangle
        Dim penGuideLine As Pen

        MyBase.OnPaint(e)

        If DesignMode Then
            penGuideLine = New Pen(SystemColors.ControlDark, 1)
            penGuideLine.DashStyle = Drawing.Drawing2D.DashStyle.Dot

            'Draw outer bounds
            wrct = ClientRectangle
            wrct.Width -= 1
            wrct.Height -= 1
            e.Graphics.DrawRectangle(penGuideLine, wrct)

            'Draw guidelines
            e.Graphics.DrawLine(penGuideLine, 21, 0, 21, ClientRectangle.Height)
            e.Graphics.DrawLine(penGuideLine, ClientRectangle.Width - 21, 0, ClientRectangle.Width - 21, ClientRectangle.Height)

            penGuideLine.Dispose()
        End If
    End Sub

    <Browsable(False)> _
    Public Overrides Property Dock() As System.Windows.Forms.DockStyle
        Get
            Return MyBase.Dock
        End Get
        Set(ByVal Value As System.Windows.Forms.DockStyle)
            'Ignore
        End Set
    End Property

    <Browsable(False)> _
    Public Overrides Property Text() As String
        Get
            Return MyBase.Text
        End Get
        Set(ByVal Value As String)
            MyBase.Text = Value
        End Set
    End Property

End Class

Friend Class WizardPageConverter
    Inherits TypeConverter

    Public Overloads Overrides Function CanConvertTo(ByVal context As ITypeDescriptorContext, _
    ByVal destType As Type) As Boolean
        If destType Is GetType(InstanceDescriptor) Then
            Return True
        End If

        Return MyBase.CanConvertTo(context, destType)
    End Function

    Public Overloads Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, _
    ByVal culture As System.Globalization.CultureInfo, _
    ByVal value As Object, ByVal destType As Type) As Object
        If destType Is GetType(InstanceDescriptor) Then
            Dim ci As System.Reflection.ConstructorInfo = _
            GetType(WizardPage).GetConstructor(System.Type.EmptyTypes)

            Return New InstanceDescriptor(ci, Nothing, False)
        End If

        Return MyBase.ConvertTo(context, culture, value, destType)
    End Function
End Class

Public Class WizardPageCollection
    Inherits CollectionBase

    Private Wizard As Wizard

    Friend Sub New(ByVal Wizard As Wizard)
        MyBase.New()

        Me.Wizard = Wizard
    End Sub

    Public Function Add(ByVal Page As WizardPage) As Integer
        Dim i As Integer

        i = List.Add(Page)
        Wizard.PageAdded(Page)

        Return i
    End Function

    Default Public ReadOnly Property Item(ByVal Index As Integer) As WizardPage
        Get
            Return DirectCast(List(Index), WizardPage)
        End Get
    End Property

    Public Sub Insert(ByVal Index As Integer, ByVal Page As WizardPage)
        List.Insert(Index, Page)
        Wizard.PageAdded(Page)
    End Sub

    Public Sub Remove(ByVal Page As WizardPage)
        Dim i As Integer = List.IndexOf(Page)

        List.Remove(Page)
        Wizard.PageRemoved(Page, i)
    End Sub

    Public Function Contains(ByVal Page As WizardPage) As Boolean
        Return List.Contains(Page)
    End Function

    Public Function IndexOf(ByVal Page As WizardPage) As Integer
        Return List.IndexOf(Page)
    End Function
End Class